﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace SemestralniPraceY35VAN
{
    class Venue
    {
        /// <summary>
        /// Properties of the venue.
        /// </summary>
        private Hashtable properties;

        /// <summary>
        /// Maps of the venue.
        /// </summary>
        private Dictionary<String, Image> maps;

        /// <summary>
        /// ID of the venue.
        /// </summary>
        public string ID { get { if (properties.ContainsKey("id")) return (string)properties["id"]; else return ""; } }

        /// <summary>
        /// Name of the venue.
        /// </summary>
        public string Name { get { if (properties.ContainsKey("name")) return (string)properties["name"]; else return ""; } }

        /// <summary>
        /// Primary category of the venue.
        /// </summary>
        public Category PrimaryCategory { get { if (properties.ContainsKey("primarycategory")) return (Category)properties["primarycategory"]; else return null; } }

        /// <summary>
        /// Address of the venue.
        /// </summary>
        public string Address { get { if (properties.ContainsKey("address")) return Convert.ToString(properties["address"]); else return ""; } }

        /// <summary>
        /// Crossing street near the venue.
        /// </summary>
        public string CrossStreet { get { if (properties.ContainsKey("crossstreet")) return (string)properties["crossstreet"]; else return ""; } }

        /// <summary>
        /// City where the venue is situated.
        /// </summary>
        public string City { get { if (properties.ContainsKey("city")) return (string)properties["city"]; else return ""; } }

        /// <summary>
        /// State where the venue is situated.
        /// </summary>
        public string State { get { if (properties.ContainsKey("state")) return (string)properties["state"]; else return ""; } }

        /// <summary>
        /// Zip code of the venue.
        /// </summary>
        public string Zip { get { if (properties.ContainsKey("zip")) return (string)properties["zip"]; else return ""; } }

        /// <summary>
        /// 
        /// </summary>
        public string Phone { get { if (properties.ContainsKey("phone")) return (string)properties["phone"]; else return ""; } }

        /// <summary>
        /// 
        /// </summary>
        public string Twitter { get { if (properties.ContainsKey("twitter")) return (string)properties["twitter"]; else return ""; } }

        /// <summary>
        /// Latitude of the venue.
        /// </summary>
        public string GeoLat { get { if (properties.ContainsKey("geolat")) return (string)properties["geolat"]; else return ""; } }

        /// <summary>
        /// Longitude of the venue.
        /// </summary>
        public string GeoLong { get { if (properties.ContainsKey("geolong")) return (string)properties["geolong"]; else return ""; } }

        /// <summary>
        /// Distance of the venue.
        /// </summary>
        public int Distance { get { if (properties.ContainsKey("distance")) return int.Parse((string)properties["distance"]); else return -1; } }
        
        /// <summary>
        /// Name of the venue.
        /// </summary>
        public Stats Stats { get { if (properties.ContainsKey("stats")) return (Stats)properties["stats"]; else return null; } }

        /// <summary>
        ///
        /// </summary>
        public List<Checkin> Checkins { get { if (properties.ContainsKey("checkins")) return (List<Checkin>)properties["checkins"]; else return null; } }

        /// <summary>
        ///
        /// </summary>
        public List<Tip> Tips { get { if (properties.ContainsKey("tips")) return (List<Tip>)properties["tips"]; else return null; } }

        /// <summary>
        ///
        /// </summary>
        public List<string> Tags { get { if (properties.ContainsKey("tags")) return (List<string>)properties["tags"]; else return null; } }

        /// <summary>
        ///
        /// </summary>
        public List<Special> Specials { get { if (properties.ContainsKey("specials")) return (List<Special>)properties["specials"]; else return null; } }

        /// <summary>
        /// Constructs an object representing a venue.
        /// </summary>
        /// <param name="venue">XML node with information about the venue</param>
        public Venue(XmlNode venue)
        {
            properties = new Hashtable();
            maps = new Dictionary<String, Image>();

            if (venue.Name == "venue")
            {
                for (int i = 0; i < venue.ChildNodes.Count; i++)
                {
                    switch (venue.ChildNodes[i].Name)
                    {
                        case "primarycategory":
                            properties.Add(venue.ChildNodes[i].Name, new Category(venue.ChildNodes[i]));
                            break;
                        case "stats":
                            properties.Add(venue.ChildNodes[i].Name, new Stats(venue.ChildNodes[i]));
                            break;
                        case "checkins":
                            List<Checkin> checkins = new List<Checkin>();

                            foreach (XmlNode checkin in venue.ChildNodes[i].ChildNodes)
                            {
                                checkins.Add(new Checkin(checkin));
                            }

                            properties.Add(venue.ChildNodes[i].Name, checkins);
                            break;
                        case "tips":
                            List<Tip> tips = new List<Tip>();

                            foreach (XmlNode tip in venue.ChildNodes[i].ChildNodes)
                            {
                                tips.Add(new Tip(tip));
                            }

                            properties.Add(venue.ChildNodes[i].Name, tips);
                            break;
                        case "tags":
                            List<string> tags = new List<string>();

                            foreach (XmlNode tag in venue.ChildNodes[i].ChildNodes)
                            {
                                tags.Add(tag.InnerText);
                            }

                            properties.Add(venue.ChildNodes[i].Name, tags);
                            break;
                        case "specials":
                            List<Special> specials = new List<Special>();

                            foreach (XmlNode special in venue.ChildNodes[i].ChildNodes)
                            {
                                specials.Add(new Special(special));
                            }

                            properties.Add(venue.ChildNodes[i].Name, specials);
                            break;
                        default:
                            properties.Add(venue.ChildNodes[i].Name, venue.ChildNodes[i].InnerText);
                            break;
                    }
                }
            }
            else
            {
                throw new IOException("Not Venue!");
            }
        }

        /// <summary>
        /// Returns map of the venue.
        /// </summary>
        /// <param name="width">width of the map</param>
        /// <param name="height">height of the map</param>
        /// <param name="zoom">zoom level</param>
        /// <returns>image with the map</returns>
        public Image GetStaticMap(short width, short height, byte zoom)
        {

            if (!maps.ContainsKey(width + "x" + height + "x" + zoom))
            {
                maps.Add(width + "x" + height + "x" + zoom, Downloader.DownloadImage(@"http://maps.google.com/maps/api/staticmap?center=" + GeoLat + "," + GeoLong + "&zoom=15&size=" + width + "x" + height + "&markers=color:red|" + GeoLat + "," + GeoLong + "|&mobile=true&sensor=true"));
            }

            return maps[width + "x" + height + "x" + zoom];
        }
    }
}
